from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View

from .models import *
from myapp.myser import *
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F

#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket

import uuid


from rest_framework import pagination

class PaginationGoods(pagination.PageNumberPagination):
	page_size = 5
	# 在不传入page_size参数时的默认长度
	page_size_query_param = 'size'
	# 设定在使用url传递参数时每页展示数量的参数名
	page_query_param = 'page'
	# 设定在使用url传递参数时展示的页数的参数名
	max_page_size = 5
	# 设定每页的最大展示数量

# 展示商品列表
class GoodsInfo(ModelViewSet):
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    
    pagination_class = PaginationGoods
    
    
    
    
# 分页器
 
 
# 展示分类列表
class CategoryInfo(ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    pagination_class = PaginationGoods
    
    
class GoodShow(APIView):
    def get(self, request):
        gid = request.GET.get('gid')
        good = Goods.objects.filter(id=gid).first()
        
        res = {}
        # 商品ID
        res['id'] = good.id
        # 商品名称给
        res['name'] = good.name
        # 商品描述
        res['desc'] = good.desc
        # 商品图片
        res['img'] = good.img
        # 演示视频
        res['video'] = good.video
        # 关注数量
        res['flow'] = good.flow
        # 价格
        res['price'] = good.price
        print(res)
        return Response({'code':200,'message':'数据获取成功','res':[res,]})  
    
import pymongo
from bson import json_util as jsonb
mongo_client = pymongo.MongoClient(host='localhost', port=27017)
# 链接数据库 
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
from django.views import View

# 基于Django插入标签的视图:
class InsertTagsHandler(View):

    def get(self,request):
        db = mongo_client.test12
        table = db.test12
        res = table.find({"title":'123'}).count()
        print(res)

        if res > 0:
            result = '重复数据'
            return HttpResponse(json.dumps({'result':result},ensure_ascii=False))
        else:
            # 往表中添加数据 
            table.insert({'title':'123','desc':['123','123']})
            return HttpResponse(json.dumps({'result':'添加成功'},ensure_ascii=False))
        
        
        
r = redis.Redis()

# 导入mongodb数据库库
import pymongo

# 导入bson
from bson import json_util as jsonb

# 将tags存入redis中
class SetRedisTages(APIView):

    def get(self,request):
        gid = request.GET.get('gid',None)
        tags = request.GET.get('tags',None)
        # 将字符串转化成列表
        tags = tags.split(',')
        # 排重
        if r.get(str(gid)):
            return Response({'code':405,'message':'此商品标签已存在'})
        r.set(str(gid),str(tags))

        return Response({'code':200,'message':'标签成功'})

class GetTags(View):

    def get(self,request):
        gid = request.GET.get('gid',None)
        # 建立数据库对象
        db = cli.md
        # 建立表对象
        table = db.mytag
        # 查询数据
        res = table.find_one({"gid":str(gid)})
        return HttpResponse(jsonb.dumps(res,ensure_ascii=False))


# 建立mongodb数据库链接
cli = pymongo.MongoClient()

# 将商品标签存入到MongoDB数据库中
class InsertTags(APIView):

    def get(self,request):
        gid = request.GET.get('gid',None)
        tags = request.GET.get('tags',None)
        # 字符串转list
        tags = tags.split(',')
        # 建立数据库对象(如果没有此数据库，则自动创建)
        db = cli.md
        # 建立表对象(如果没有此表，则自动创建)
        table = db.mytag

        # 排重
        res = table.find({'gid':str(gid)}).count()

        if res > 0:
            return Response({'message':'标签已存在'})

        table.insert({'gid':str(gid),'tags':tags})
        return Response({'message':'入库成功'})
    
    

class InsertComment(ModelViewSet):
    queryset = Comments.objects.all()
    serializer_class = CommentsSerializer
    

class ShowComment(APIView):
    def get(self, request):
        gid = request.GET.get('gid', None)
        comments = Comments.objects.filter(gid=gid)
        res = {}
        res['code'] = 200
        res['message'] = '评论获取成功'
        if comments:
            res['comments'] = comments
        else:
            res['comments'] = ''
            
        return Response(res)
    
    
    

# 评论列表
class CommentList(APIView):
    def get(self, request):
        resp = {}
        # 商品id
        gid = int(request.GET.get('gid'))
        # 默认第一页
        page = int(request.GET.get('page', 1))
        # 一页显示多少条
        size = int(request.GET.get('size', 5))
        # 从哪个位置开始切
        comment_start = (page - 1) * size
        # 切到哪个位置
        comment_end = page * size
        # 查询评论
        comment = Comment.objects.filter(gid=gid).order_by('-create_time')[comment_start:comment_end]
        # 查询总共有多少条评论
        sum_number = Comment.objects.filter(gid=gid).count()
        print(sum_number)
        # 序列化
        comment_ser = CommentSer(comment, many=True).data
        resp['total'] = sum_number
        resp['comment_ser'] = comment_ser
        return Response(resp)


# 反序列化入库(商品评论)
class InsertComment(APIView):
    # 将商品评论存入到MongoDB数据库中
    def get(self, request):
        # 建立数据库对象(如果没有此数据库，则自动创建)
        db = cli.md
        # 建立表对象(如果没有此表，则自动创建)
        table = db.comment
        # 获取数据
        gid = request.GET.get('gid', None)
        uid = request.GET.get('uid', None)
        content = request.GET.get('content', None)
        table.insert({'gid': gid, 'uid': uid, 'content': content})

        return Response({'message': '入库成功'})

    def post(self, request):
        # 初始化参数
        comment = CommentSer(data=request.data)
        if comment.is_valid():
            # 数据入库
            comment.save()
            return Response({'code': 200, 'message': '评论成功'})

        return Response({'code': 405, 'message': '评论失败'})


# 统计商品访问次数
class VisitGoods(APIView):
    def get(self, request):
        # 获取用户信息及用户访问的商品id
        uid = request.GET.get('uid')
        gid = request.GET.get('gid')
        # 判断该用户是否第一次访问此商品
        if r.llen('uid' + uid) < 1:
            # 将访问商品id与访问时间的分钟写入到redis中
            curr_time = datetime.datetime.now().minute
            # gid做键,当前时间做值
            r.sadd('gid' + gid, curr_time)
            # uid做键, gid做值
            r.lpush('uid' + uid, gid)
            print('第一次访问')
        else:
            # 获取上次访问的时间
            last_time = r.smembers('gid' + gid)
            # 转码
            last_time = str(list(last_time)[0], 'utf-8')
            last_time = int(last_time)
            # 获取当前时间中的分钟
            curr_time = int(datetime.datetime.now().minute)
            # 判断访问间隔是否大于一分钟
            if curr_time - last_time > 1:
                # 将访问商品id与访问时间的 分钟写入到redis中
                curr_time = datetime.datetime.now().minute
                r.sadd('gid' + gid, curr_time)
                r.lpush('uid' + uid, gid)
                print('访问时间超过一分钟')
            else:
                pass
                print('访问时间不到一分钟')
        return Response({'商品访问次数': r.llen('uid' + uid)})


# 统计在线人数
class GetOnLine(APIView):
    def get(self, request):
        # 获取客户ip
        if 'HTTP_X_FORWARDED_FOR' in request.META:
            ip = request.META.get('HTTP_X_FORWARDED_FOR')
        else:
            ip = request.META.get('REMOTE_ADDR')

        # 对用户ip进行存储
        r.sadd('online', ip)
        # 设置超时时间 超时时长单位秒
        r.expire('online', 25)
        # 获取在线人数数量
        myset = r.smembers('online')
        return Response({'online': len(myset)})
    
    
# 导入时间模块
import datetime

# 对结果集美化方法
def dictfetchall(cursor):
    # 获取游标描述
    desc = cursor.description
    return [
        dict(zip([col[0] for col in desc],row))
        for row in cursor.fetchall()
    ]

# 查询商品关注人数及用户名(查询用户关注过的商品列表)
class GoodFlow(View):
    def get(self,request):
        # 接收查询的商品id
        gid = request.GET.get('gid',None)
        # 建立游标对象
        cursor = connection.cursor()
        # 执行sql语句
        cursor.execute('select a.username from user a left join userflow b on a.id = b.uid where b.gid = %s' % str(gid))
        # 获取结果
        resp = dictfetchall(cursor)
        # 返回结果 (手动序列化)
        return HttpResponse(json.dumps(resp,ensure_ascii=False),content_type='application/json')

# 商品关注接口(查询用户关注过的商品列表)
class UidFlow(View):
    def get(self,request):
        # 接收用户
        uid = request.GET.get('uid',None)
        # 建立游标对象
        cursor = connection.cursor()
        # 执行sql语句
        cursor.execute('select a.name from goods a left join userflow b on a.id = b.gid where b.uid = %s' % str(uid))
        # 获取结果
        # resp = cursor.fetchall()
        resp = dictfetchall(cursor)
        # 返回结果 (手动序列化)
        return HttpResponse(json.dumps(resp,ensure_ascii=False),content_type='application/json')
    
    
#关注商品接口(取关)
class GetFlow(APIView):

	def get(self,request):

		id = request.GET.get("id",None)
		uid = request.GET.get("uid",None)
		type = request.GET.get("type",1)

		if int(type) == 1:

			#关注
			userflow = UserFlow(gid=int(id),uid=int(uid))
			try:
				userflow.save()
				message = "关注成功"
				goods = Goods.objects.filter(id=int(id)).first()
				goods.flow = goods.flow + 1
				goods.save()
			except Exception as e:
				print(str(e))
				message = "不能重复关注"
				pass
			
		else:
			#取关
			UserFlow.objects.filter(gid=int(id),uid=int(uid)).delete()
			message = "取关成功"
			goods = Goods.objects.filter(id=int(id)).first()
			goods.flow = goods.flow - 1
			goods.save()

		return Response({'message':message})


#工具方法，获取前n名的数据
def get_top_n(num):

	#获取redis数据
	goods_click = r.zrange('good_rank',0,-1,desc=True,withscores=True)[:num]
	#获取mysql数据
	goods = Goods.objects.in_bulk([int(item[0]) for item in goods_click])

	#合并操作
	res = []
	for item in goods_click:

		#遍历列表
		res.append({int(item[1]):goods[int(item[0])]})

	print(res)

	return res


#商品排行榜数据视图
class GoodRank(APIView):

	def get(self,request):

		#获取排名前n的数据
		get_res = get_top_n(10)

		res = []
		#遍历进行序列化
		for dic in get_res:
			for key,value in dic.items():
				#序列化
				data = GoodsSerializer(value).data
				#将商品点击数附加到商品序列化数据中
				data['clicks'] = key
				res.append(data)

		#返回
		return Response(res)



#新的商品参与排名
class GoodsClick(APIView):

	def get(self,request):

		#接收参数
		id = request.GET.get("id",None)

		#修改商品的点击数
		r.zincrby("good_rank",1,int(id))

		get_top_n(10)

		return Response({"message":"访问加1"})

# 搜索框事件
class GoodsSearch(APIView):
    def get(self, request):
        word = request.GET.get('word', None)
        print(word)
        goodlist = Goods.objects.filter(name__icontains=word)
        if goodlist:
        
            good_ser = GoodsSerializer(goodlist,many=True).data
        else:
            return Response({'code': 201,'message': '没有查询到对应的数据'})
        # print(goodlist)
        
        return Response({'code': 200,'message': '查询成功'})